/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.clinicplus.manager;

import br.com.foxline.clinicplus.entity.*;
import br.com.foxline.clinicplus.enums.PaymentType;
import br.com.foxline.clinicplus.enums.SituationAppraisal;
import br.com.foxline.clinicplus.enums.TypeItem;
import br.com.foxline.clinicplus.service.*;
import br.com.foxline.clinicplus.util.Msg;
import java.io.Serializable;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerAppraisal implements Serializable {

    @EJB
    TemplateAppraisalService templateAppraisalService;
    @EJB
    AppraisalService appraisalService;
    @EJB
    DiaryService diaryService;
    @EJB
    SystemUserService systemUserService;
    @EJB
    DoctorService doctorService;
    @EJB
    CategoryService categoryService;
    @EJB
    ItemService itemService;
    private Appraisal appraisal;
    private TemplateAppraisal templateAppraisal;
    private TemplateAppraisal novoTemplateAppraisal;
    private Diary diary;
    private Procedure procedure;
    private Long idDiary;
    private TreeNode root;
    private TreeNode[] selectedNodes;
    private String searchName;
    private String text;
    private List<TemplateAppraisal> templateAppraisals;
    private String edit;
    private String show;
    private boolean finalizar;
    private boolean aprovandoLaudo;
    private boolean entregar;
    private Doctor doctor;
    private Doctor doctorSelected;
    private String nameDoctor;
    private List<Doctor> doctors;
    private String backedit;
    
    private String frase;
    private List<Item> frases;
    
    @PostConstruct
    public void init() {
        appraisal = new Appraisal();

        doctor = new Doctor();

        Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        edit = params.get("appraisalEdit");
        show = params.get("appraisalShow");
        backedit = params.get("backedit");

        params();
        
        novoTemplateAppraisal = new TemplateAppraisal();

    }

    public List<SelectItem> selectSituationAppraisal() {
        List<SelectItem> paymentTypes = new ArrayList<SelectItem>();
        for (SituationAppraisal ms : SituationAppraisal.values()) {
            paymentTypes.add(new SelectItem(ms, ms.getDesc()));
        }
        return paymentTypes;
    }

    public Doctor getDoctor() {
        return doctor;
    }

    public void setDoctor(Doctor doctor) {
        this.doctor = doctor;
    }

    public Doctor getDoctorSelected() {
        return doctorSelected;
    }

    public void setDoctorSelected(Doctor doctorSelected) {
        this.doctorSelected = doctorSelected;
    }

    public List<Doctor> getDoctors() {
        return doctors;
    }

    public void setDoctors(List<Doctor> doctors) {
        this.doctors = doctors;
    }

    public String getNameDoctor() {
        return nameDoctor;
    }

    public void setNameDoctor(String nameDoctor) {
        this.nameDoctor = nameDoctor;
    }

    public boolean isAprovandoLaudo() {
        return aprovandoLaudo;
    }

    public void setAprovandoLaudo(boolean aprovandoLaudo) {
        this.aprovandoLaudo = aprovandoLaudo;
    }

    public boolean isEntregar() {
        return entregar;
    }

    public void setEntregar(boolean entregar) {
        this.entregar = entregar;
    }

    private void params() {
        if (edit != null) {

            try {

                appraisal = appraisalService.find(Long.parseLong(edit));

                if (backedit != null) {
                    appraisal.setSituationAppraisal(SituationAppraisal.PRODUCTION);
                }

                if (appraisal.getSituationAppraisal() == SituationAppraisal.FINISHED
                        || appraisal.getSituationAppraisal() == SituationAppraisal.DELIVERED) {
                    entregar = true;
                }

                diary = appraisal.getDiary();
                idDiary = appraisal.getDiary().getId();
                if (appraisal.getTemplateAppraisal() != null) {
                    templateAppraisal = appraisal.getTemplateAppraisal();
                }

                if (diary.getProcedure() != null && appraisal.getTitle() != null && !appraisal.getTitle().isEmpty()) {
                    appraisal.setTitle(diary.getProcedure().getName());
                }

                treeCheckboxBean();

                if (appraisal.getText() != null && appraisal.getText().trim().equalsIgnoreCase(appraisal.getTextEdit().trim())) {
                    text = gerarTexto();
                } else {
                    text = appraisal.getTextEdit();
                }
                doctor = appraisal.getDoctorResponse();
            } catch (Exception e) {
                e.printStackTrace();
                Msg.messagemError("Laudo não encontrado!");
            }
        } else {
            finalizar = true;
        }
    }

    public String getSearchName() {
        return searchName;
    }

    public void setSearchName(String searchName) {
        this.searchName = searchName;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public TreeNode[] getSelectedNodes() {
        return selectedNodes;
    }

    public void setSelectedNodes(TreeNode[] selectedNodes) {
        this.selectedNodes = selectedNodes;
    }

    public TreeNode getRoot() {
        return root;
    }

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public Diary getDiary() {
        return diary;
    }

    public void setDiary(Diary diary) {
        this.diary = diary;
    }

    public Long getIdDiary() {
        return idDiary;
    }

    public void setIdDiary(Long idDiary) {
        this.idDiary = idDiary;
    }

    public Procedure getProcedure() {
        return procedure;
    }

    public void setProcedure(Procedure procedure) {
        this.procedure = procedure;
    }

    public TemplateAppraisal getTemplateAppraisal() {
        return templateAppraisal;
    }

    public void setTemplateAppraisal(TemplateAppraisal templateAppraisal) {
        this.templateAppraisal = templateAppraisal;
    }

    public Appraisal getAppraisal() {
        return appraisal;
    }

    public void setAppraisal(Appraisal appraisal) {
        this.appraisal = appraisal;
    }

    public List<TemplateAppraisal> getTemplateAppraisals() {
        return templateAppraisals;
    }

    public void setTemplateAppraisals(List<TemplateAppraisal> templateAppraisals) {
        this.templateAppraisals = templateAppraisals;
    }

    public void loadDiary() {
        diary = diaryService.find(idDiary);
        if (diary == null) {
            Msg.messagemError("Ficha inexistente. Verifique o código.");
            return;
        }
        appraisal.setCustomer(diary.getCustomer());
        appraisal.setDiary(diary);
        if (diary.getProcedure() != null) {
            appraisal.setTitle(diary.getProcedure().getName());
        }
    }

    public void treeCheckboxBean() {
        if (templateAppraisal == null || templateAppraisal.getCategorys() == null) {
            return;
        }
        root = new DefaultTreeNode("Root", null);

        for (Category category : templateAppraisal.getCategorys()) {
            TreeNode cat = new DefaultTreeNode(category, root);
            cat.setSelectable(false);
            cat.setExpanded(true);
            for (Item item : category.getItems()) {

                if (item.isItemDefault() && appraisal.getItens() == null) {
                    item.setSelect(true);
                }
                TreeNode i = new DefaultTreeNode(item, cat);

                if (item.isItemDefault() && appraisal.getItens() == null) {
                    i.setSelected(true);
                }

                if (appraisal.getItens() != null && appraisal.getItens().contains(item)) {
                    i.setSelected(true);
                    item.setSelect(true);
                }
            }
        }
    }

    public void addTemplate(int id) {
        templateAppraisal = templateAppraisals.get(id);
        templateAppraisal.setCategorys(categoryService.getByOrdemAsc(templateAppraisal));

        for (Category category : templateAppraisal.getCategorys()) {
            category.setItems(itemService.getByOrdemAsc(category));
        }

        treeCheckboxBean();
        text = gerarTexto();
    }

    public String getEdit() {
        return edit;
    }

    public void setEdit(String edit) {
        this.edit = edit;
    }

    public void save() {

        try {

            if (finalizar) {
                appraisal.setSituationAppraisal(SituationAppraisal.FINISHED);
            } else {
                appraisal.setSituationAppraisal(SituationAppraisal.PRODUCTION);
            }

            appraisal.setTextEdit(text);
            appraisal.setText(gerarTexto());
            appraisal.setTemplateAppraisal(templateAppraisal);

            List<Item> selected = new ArrayList<Item>();

            if (templateAppraisal != null && templateAppraisal.getCategorys() != null) {
                for (Category category : templateAppraisal.getCategorys()) {

                    for (Item item : category.getItems()) {
                        if (item.isSelect()) {
                            selected.add(item);
                        }
                    }
                }
            }

            appraisal.setItens(selected);
            if (doctor != null && doctor.getId() != null) {
                appraisal.setDoctorResponse(doctor);
            }

            if (appraisal != null && appraisal.getId() == null) {
                appraisal.setCreatAt(new Date());
                appraisal.setSystemUser(systemUserService.getCurrentUser());
                appraisalService.save(appraisal);
            } else {
                appraisal.setUpdateAt(new Date());
                appraisal.setSystemUserAppraisalEdit(systemUserService.getCurrentUser());
                appraisalService.update(appraisal);
            }

            RequestContext context = RequestContext.getCurrentInstance();
            context.execute("dlgPrint.show();");
        } catch (Exception e) {
            e.printStackTrace();
            Msg.messagemError("Erro na operação!");
        }
    }

    public void entregarLaudo() {
        try {
            appraisal.setDateDelivery(new Date());
            appraisal.setSituationAppraisal(SituationAppraisal.DELIVERED);
            appraisal.setSystemUserAppraisal(systemUserService.getCurrentUser());
            appraisalService.update(appraisal);
            RequestContext context = RequestContext.getCurrentInstance();
            context.execute("dlgDeliveredAppraisal.hide();");
            Msg.messagemInfo("Operação realizada com Sucesso!");
        } catch (Exception e) {
            e.printStackTrace();
            Msg.messagemError("Erro ao realizar a operação.");
        }

    }

    public void print() {
        System.err.println(text);
        appraisal.setTextEdit(text);
        appraisal.setText(gerarTexto());


        text = text.replaceAll("\\<strong\\>", "<b>");
        text = text.replaceAll("\\<\\/strong\\>", "</b>");
        text = text.replaceAll("\\<em\\>", "<i>");
        text = text.replaceAll("\\<\\/em\\>", "</i>");

        text = text.replaceAll("\\<style type=\"text\\/css\"\\>.*\\<\\/style\\>", "");

        appraisalService.genReport(text, appraisal);

        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("dlgPrint.hide();");
    }

    public void searchTemplate() {
        TemplateAppraisal ta = new TemplateAppraisal();
        ta.setName(searchName);

        templateAppraisals = templateAppraisalService.find(ta);

    }

    public void backTextOrigin() {
        text = gerarTexto();
    }

    private String gerarTextoOld() {
        String text;
        text = "";
        text += "<ul>";

        if (templateAppraisal != null) {
            for (Category c : templateAppraisal.getCategorys()) {
                if (!c.isOmitirTitulo()) {
                    text += "<li style=\"list-style: none;\">";
                    text += "<div class=\"" + c.getTitulo().trim().toUpperCase() + "\" style=\"margin: 6px 0;\">";
                    text += "<b>" + c.getTitulo().toUpperCase() + "</b>";
                    text += "</div>";
                }
                text += "<div class=\"" + c.getTitulo().trim().toUpperCase() + "_CONTENT\">";

                for (Item i : c.getItems()) {
                    if (i.isSelect()) {
                        if (i.getTypeItem() == TypeItem.TEXTO) {
                            text += i.getDescricao() + " ";
                        } else {
                            text += i.getDescricao() + "<br/>";
                        }
                    }
                }

                text += "</div>";
                if (!c.isOmitirTitulo()) {
                    text += "</li>";
                }
            }
        }
        text += "</ul>";


        return text;

    }
    
    private String gerarTexto() {
        String text = "";
        
        if(templateAppraisal != null && templateAppraisal.getTextModel() != null && !templateAppraisal.getTextModel().isEmpty()){
            return templateAppraisal.getTextModel();
        }
        
        if (templateAppraisal != null) {
            for (Category c : templateAppraisal.getCategorys()) {
                if (!c.isOmitirTitulo()) {
                    text += "<br/>";
                    text += "<br/>";
                    text += "<b>" + c.getTitulo().toUpperCase() + "</b>";
                    text += "<br/>";
                }
                for (Item i : c.getItems()) {
                    if (i.isSelect()) {
                        if (i.getTypeItem() == TypeItem.TEXTO) {
                            text += i.getDescricao() + " ";
                        } else {
                            text += i.getDescricao() + "<br/>";
                        }
                    }
                }

            }
        }


        return text;

    }

    public void onNodeSelect(NodeSelectEvent event) {
        if (event.getTreeNode().getData() instanceof Item) {
            ((Item) event.getTreeNode().getData()).setSelect(true);
        }

        this.text = gerarTexto();
    }

    public void onNodeUnselect(NodeUnselectEvent event) {
        if (event.getTreeNode().getData() instanceof Item) {
            ((Item) event.getTreeNode().getData()).setSelect(false);
        }
        this.text = gerarTexto();
    }

    public boolean isFinalizar() {
        return finalizar;
    }

    public void setFinalizar(boolean finalizar) {
        this.finalizar = finalizar;
    }

    public void listDoctor() {
        Doctor d = new Doctor();
        d.setName(nameDoctor);
        doctors = doctorService.findDoctor(d);
    }

    public void selectDoctor() {
        doctor = doctorSelected;
    }

    public void clearDoctor() {
        doctorSelected = null;
        doctor = null;
    }

    public TemplateAppraisal getNovoTemplateAppraisal() {
        return novoTemplateAppraisal;
    }

    public void setNovoTemplateAppraisal(TemplateAppraisal novoTemplateAppraisal) {
        this.novoTemplateAppraisal = novoTemplateAppraisal;
    }
    
    
    
    public void salvarModelo() {
        try {
            novoTemplateAppraisal.setTextModel(text);
            novoTemplateAppraisal.setCreateAt(new Date());
            novoTemplateAppraisal.setSystemUser(systemUserService.getCurrentUser());
            templateAppraisalService.save(novoTemplateAppraisal);
            Msg.messagemInfo("Modelo salvo com Sucesso !");
            init();
        } catch (Exception e) {
            Msg.messagemInfo("Erro na Operação!");
        }

    }

    public String getFrase() {
        return frase;
    }

    public void setFrase(String frase) {
        this.frase = frase;
    }
    
    public void pesquisarFrase(){
        frases = itemService.pesquisarFrase(frase);
        
    }

    public List<Item> getFrases() {
        return frases;
    }

    public void setFrases(List<Item> frases) {
        this.frases = frases;
    }
    
    
    
}
